package com.carlinfo.userscenter.common.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


/**
 * ~标准的JDBC
 * ~单例模式:什么是单例模式:在一个JVM中,只有一个对象
 * 		让构造方法私有
 * 		提供一个属性;类型是自己,new一个对象
 * 		提供一个方法返回值是 自己,修饰符是public static
 * ~封装JDBC
 * 		将加载驱动只执行一次
 * 		第二个放到一个方法中
 * 		将经常修改的内容放到配置文件中;资源文件,ResourceBundle
 * @author JayLong
 *
 */
public class DbUtil
{
	/* 为了属性的安全:设置值和获取值(set/get) */
	//恶汉式
	private static DbUtil INSTANCE = new DbUtil();
	//变量 
	/*private String driver = "com.mysql.jdbc.Driver";
	private String url = "jdbc:mysql://localhost:3306/userscenter_20180916?useSSL=true";
	private String user = "root";
	private String password = "123456";
	Connection connection = null;*/
	
	//变量 
	private String driver = ConstatFinalUtil.BUNDLE.getString("jdbc.driver");
	private String url = ConstatFinalUtil.BUNDLE.getString("jdbc.url");
	private String user = ConstatFinalUtil.BUNDLE.getString("jdbc.user");
	private String password = ConstatFinalUtil.BUNDLE.getString("jdbc.password");
	Connection connection = null;
	/**
	 * ~私有的构造方法
	 */
	private DbUtil()
	{
		//单例模式
		try
		{
			/* 加载驱动  */
			Class.forName(driver);
		} catch (ClassNotFoundException e)
		{
			System.out.println("===加载驱动失败===");
			e.printStackTrace();
		}
	}
	/**
	 * ~static:构造方法私有了,外面的类不能new了,如果此方法不能被static修饰,那么getInstance,是必须得new,只能被static修饰
	 * @param args
	 */
	public static DbUtil getInstance()
	{
		return INSTANCE ;
	}
	/*
	 * ~获取一个连接 
	 */
	public Connection getConnection()
	{
		try
		{
			//获取链接 
		    connection = DriverManager.getConnection(url, user, password);
		} catch (SQLException e)
		{
			System.out.println("===获取连接失败===");
			e.printStackTrace();
		}
		return connection ;
	}
	
	/**
	 * ~关闭链接,关闭语句,关闭rs
	 * @param args
	 */
	public void closeAll(Connection connection , Statement st , ResultSet rs)
	{
		try
		{
			if(rs != null)
			{
				rs.close();
				rs = null;
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
		try
		{
			if(st !=  null)
			{
				st.close();
				st = null;
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
		try
		{
			if(connection != null)
			{
				connection.close();
				connection  = null;
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
	}
	public static void main(String[] args)
	{
		//stardandJDBC();
		encapsulationJDBC();
		
		/* 测试单例模式  */
		for (int i = 0; i < 10 ; i++)
		{
			//单例模式不能new对象,要使用getInstance方法
			System.out.println(DbUtil.getInstance());
		}
	}
	/**
	 * ~封装后的JDBC
	 */
	public static void encapsulationJDBC()
	{
		System.out.println("==封装后的JDBC==");
		String sql = "select * from a_role";
		PreparedStatement ps = null;
		ResultSet rs = null;
		//先创建对象,不能new
		DbUtil dbUtil = DbUtil.getInstance();
		//获取链接
		Connection connection = dbUtil.getConnection();
		try
		{
			ps = connection.prepareStatement(sql);
			rs = ps.executeQuery();
			/* 到底如何选择循环还是选择
			 * ~如果查询的结果是多条,就用判断
			 * ~如果是单条:就用选择 
			 * 
			 * rs == 班长  == 迭代器 == enumeration(枚举)
			 *   */
			while(rs.next())
			{
				/*
				 * ~参数为整数:指的是sql语句 执行以后 ;列的顺序 
				 * ~参数为字符串时:指的是sql语句执行以后列的别名
				 * */
				int id = rs.getInt(1);
				String name = rs.getString("name");
				System.out.println("id:" + id + ";name:" + name);
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		}finally
		{
			dbUtil.closeAll(connection, ps, rs);
		}
	}
	/*
	 * ~标准的JDBC代码
	 * ~查询角色表中所有的记录
	 */
	private static void stardandJDBC()
	{
		/* 
		 * JDBC四步走
		 *  	加载驱动 
		 *  	获取链接
		 *  	操作数据库
		 *  	关闭连接
		 * */
		/* 获取角色表中所有的记录  */
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/userscenter_20180916?useSSL=true";
		String user = "root";
		String password = "123456";
		String sql = "select * from a_role";
		Connection connection = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try
		{
			/* 加载驱动  */
			Class.forName(driver);
			/* 获取链接  */
			connection = DriverManager.getConnection(url, user, password);
			/* 操作数据库
			 * ~创建一个SQL语句,将SQL语句发送到数据库中
			 * Statement:没有预先加载
			 * preparedStatement:预先加载
			 *  */
			ps = connection.prepareStatement(sql);
			rs = ps.executeQuery();
			/* 到底如何选择循环还是选择
			 * ~如果查询的结果是多条,就用判断
			 * ~如果是单条:就用选择 
			 * 
			 * rs == 班长  == 迭代器 == enumeration(枚举)
			 *   */
			while(rs.next())
			{
				/*
				 * ~参数为整数:指的是sql语句 执行以后 ;列的顺序 
				 * ~参数为字符串时:指的是sql语句执行以后列的别名
				 * */
				int id = rs.getInt(1);
				String name = rs.getString("name");
				System.out.println("id:" + id + ";name:" + name);
			}
			
		} catch (ClassNotFoundException e)
		{
			System.out.println("====加载驱动失败====");
			e.printStackTrace();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}finally
		{
			try
			{
				if(rs != null)
				{
					rs.close();
					rs = null;
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
			try
			{
				if(ps !=  null)
				{
					ps.close();
					ps =  null;
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
			try
			{
				if(connection != null)
				{
					connection.close();
					connection  = null;
				}
			} catch (SQLException e)
			{
				e.printStackTrace();
			}
		}
	}
}
